type Decorator
    &(Component) => Component;

export function with:
    &(Component, Decorator) => Component
    &(cpt, f) => { f(cpt) };

export function with:
    &(Component, List[Decorator]) => Component
    &(cpt, @f) => cpt.{apply-all @f.{Seq}};

/*
export function with:[T]
    &((&(T) => Component), Decorator) => (&(T) => Component)
    &(ctor, f) => (&(arg) => { f { ctor(arg) } });

export function with:[T]
    &((&(T) => Component), List[Decorator]) => (&(T) => Component)
    &(ctor, @f) => (&(arg) => {ctor(arg)}.{apply-all @f.{Seq}});
*/

export function RenderCond:
    &(Computed[Bool]) => Decorator
    &(@render) => &(cpt) =>
        \ render := switch-map @render,
        if render:
            cpt,
        else:
            Empty;

export function ShowCond:
    &(Computed[Bool]) => Decorator
    &(@show) => &(@node) =>
        \ (node, show) := Computed (@node, @show),
        if show:
            node,
        else:
            (node with { Styles [('display','none')] });

export function Style:
    &(List[String]) => Decorator
    &(class-list) => &(@node) =>
        let class := (class-list join ' '),
        (@node map &(node) => (node with { Attrs [('class',class)] }));

export function Style:
    &(Computed[List[String]]) => Decorator
    &(@class-list) => &(@node) =>
        \ (class-list, node) := Computed (@class-list, @node),
        let class := (class-list join ' '),
        (node with { Attrs [('class',class)] });

export function InlineStyle:
    &(List[(String,String)]) => Decorator
    &(rules) => &(@node) =>
        \ node := map @node,
        (node with { Styles rules });

export function InlineStyle:
    &(Computed[List[(String,String)]]) => Decorator
    &(@rules) => &(@node) =>
        \ (rules, node) := Computed (@rules, @node),
        (node with { Styles rules });

export function Event:
    &(String,EventPayloadConsumer) => Decorator
    &(name,consumer) => &(@node) =>
        let handler := consumer.{EventHandler},
        \ node := map @node,
        (node with { Events [(name,handler)] });

export function Focusable:
    &() => Decorator
    &() => &(@node) =>
        \ node := map @node,
        (node with { Attrs [('tabindex','0')] });

export function Autofocus:
    &() => Decorator
    &() => &(@node) =>
        \ node := map @node,
        (node with { Attrs [('webuiAutofocus','webuiAutofocus')] });

export function EnableCond:
    &(Computed[Bool]) => Decorator
    &(@enabled) => &(@node) =>
        \ (enabled, node) := Computed (@enabled, @node),
        if enabled:
            node,
        else:
            (node with { Attrs [('disabled', 'disabled')] });
